//
//  测试获取某个窗口内的控件的文本内容
// Created by hugan on 2021/12/29.
//
#include <iostream>
#include <Windows.h>
#include <processthreadsapi.h>
#include <winternl.h>
#include <memoryapi.h>

using namespace std;

/**
 * @param hWnd
 * @param lParam
 * @return true-继续遍历,false-停止遍历
 */
BOOL CALLBACK EnumChildProc(HWND hWnd, LPARAM lParam) {
    char componentName[256];
    ::GetClassName(hWnd, componentName, 255);
    if (::strcmp(componentName, "Edit") == 0) {
        //获取文本
        char text[256];
        ::SendMessage(hWnd, WM_GETTEXT, sizeof(text) / sizeof(char), (LPARAM) text);
        cout << "text=" << text << endl;
//        return false;
        return true;
    } else if (::strcmp(componentName, "CefBrowserWindow") == 0) {
        cout << "CefBrowserWindow=" << endl;
        ::EnumChildWindows(hWnd, EnumChildProc, 0);
        return false;
    } else {
        cout << "component=" << componentName << endl;
        return true;
    }
}

void testEnumChildProc(HWND hWnd) {
    ::EnumChildWindows(hWnd, EnumChildProc, 0);
}

void test2(HWND hWnd) {
    char componentName[256];
    while (hWnd) {
        ::GetClassName(hWnd, componentName, 255);
        cout << "component=" << componentName << endl;

        hWnd = GetWindow(hWnd, GW_HWNDNEXT);
    }
}

/**
 * 获取程序启动入参
 * @param dwPID 程序pid
 * @note 如果当前程序权限比目标程序低,则会报错,拒绝访问,LOL也会!!?
 */
int WINAPI GetProcessCommandLine(DWORD dwPID, LPTSTR lpszCommandLine, DWORD dwByteOfSize) {
    //另一种方法:wmic process where name="LeagueClientUx.exe" get commandline,也有权限问题
    //https://bbs.csdn.net/topics/380196754?page=2
    HANDLE hProcess = ::OpenProcess(PROCESS_CREATE_THREAD | PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ,
                                    FALSE, dwPID);

    if (!hProcess) {
        return 0;
    }

    DWORD dwThreadId = 0;
    DWORD dwExitCode = 0;
    DWORD dwReaded = 0;
    HANDLE hThread = ::CreateRemoteThread(hProcess, NULL, NULL, (LPTHREAD_START_ROUTINE) GetCommandLine, NULL, 0,
                                          &dwThreadId);

    if (hThread) {
        ::WaitForSingleObject(hThread, INFINITE);
        ::GetExitCodeThread(hThread, &dwExitCode);
        ::ReadProcessMemory(hProcess, (LPCVOID) dwExitCode, lpszCommandLine, dwByteOfSize,
                            reinterpret_cast<SIZE_T *>(&dwReaded));
    }

    return dwReaded;
}

void processInfo() {
    LPTSTR aa2 = new TCHAR[10240];
    int readCount = GetProcessCommandLine(2512, aa2, 10240);
    cout << "readCount=" << readCount << endl;
}

int main() {
    cout << "main.st" << endl;

    //进程名,或标题名
    HWND hWnd = ::FindWindow("notepad", NULL);
    //HWND hWnd = ::FindWindow("notepad++", NULL);
////    HWND hWnd = ::FindWindow(NULL, "League of Legends");
    if (hWnd) {
        testEnumChildProc(hWnd);
//        test2(hWnd);
    } else {
        cout << "none window" << endl;
    }
    //processInfo();
    cout << "main.ed" << endl;
    return 0;
}